package com.dinzeer.legendreliclib.lib.compat.slashblade.entity.swordrain;

import com.dinzeer.legendreliclib.lib.compat.slashblade.SlashBladeCompatEntities;
import mods.flammpfeil.slashblade.SlashBlade;
import mods.flammpfeil.slashblade.ability.StunManager;
import mods.flammpfeil.slashblade.entity.EntityAbstractSummonedSword;
import mods.flammpfeil.slashblade.entity.Projectile;
import mods.flammpfeil.slashblade.util.KnockBacks;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.network.PlayMessages;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;

/**
 * SwordRainEntity 类表示剑雨实体，继承自 EntityAbstractSummonedSword。
 * 用于创建和管理剑雨效果，包括发射、追踪目标和命中效果。
 */
public class BaseSwordRainEntity extends EntityAbstractSummonedSword {
    public static final EntityDataAccessor<Boolean> IT_FIRED;
    public static final EntityDataAccessor<Boolean> FORWARD;
    public static final EntityDataAccessor<Boolean> VISIBLE;

    /** 地面存在时间常量 */
    public static final int ON_GROUND_LIFE_TIME = 20;
    /** 基础延迟时间 */
    public static final int BASE_DELAY = 10;
    /** 默认滚动角度 */
    public static final float DEFAULT_ROLL = -90.0F;

    /** 发射时间 */
    long fireTime = -1L;
    /** 在地面的计时器 */
    public int ticksInGround = 0;
    /** 滚动角度 */
    public float roll = DEFAULT_ROLL;

    static {
        IT_FIRED = SynchedEntityData.defineId(BaseSwordRainEntity.class, EntityDataSerializers.BOOLEAN);
        FORWARD = SynchedEntityData.defineId(BaseSwordRainEntity.class, EntityDataSerializers.BOOLEAN);
        VISIBLE = SynchedEntityData.defineId(BaseSwordRainEntity.class, EntityDataSerializers.BOOLEAN);
    }

    /**
     * 构造函数，初始化剑雨实体。
     *
     * @param entityTypeIn 实体类型
     * @param worldIn      所在世界
     */
    public BaseSwordRainEntity(EntityType<? extends BaseSwordRainEntity> entityTypeIn, Level worldIn) {
        super(entityTypeIn, worldIn);
        this.setPierce((byte) 5);

        // 添加移动减速效果
        CompoundTag compoundtag = this.getPersistentData();
        ListTag listtag = compoundtag.getList("CustomPotionEffects", 9);
        MobEffectInstance mobeffectinstance = new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 20, 10);
        listtag.add(mobeffectinstance.save(new CompoundTag()));
        this.getPersistentData().put("CustomPotionEffects", listtag);
    }

    @Override
    protected void defineSynchedData() {
        super.defineSynchedData();
        this.entityData.define(IT_FIRED, false);
        this.entityData.define(FORWARD, false);
        this.entityData.define(VISIBLE, false);
    }

    /**
     * 获取滚动角度。
     *
     * @return 滚动角度
     */
    @Override
    public float getRoll() {
        return roll;
    }

    /**
     * 设置滚动角度。
     *
     * @param roll 滚动角度
     */
    @Override
    public void setRoll(float roll) {
        this.roll = roll;
    }

    /**
     * 判断实体是否隐形。
     *
     * @return 如果向前且不可见则返回true，否则返回父类方法结果
     */
    @Override
    public boolean isInvisible() {
        if (this.getEntityData().get(FORWARD) && !this.getEntityData().get(VISIBLE)) {
            return true;
        }
        return super.isInvisible();
    }

    /**
     * 设置前进方向。
     *
     * @param isForward 是否向前
     */
    public void setForward(boolean isForward) {
        this.getEntityData().set(FORWARD, isForward);
    }

    /**
     * 标记实体已发射。
     */
    public void doFire() {
        this.getEntityData().set(IT_FIRED, true);
    }

    /**
     * 检查实体是否已发射。
     *
     * @return 是否已发射
     */
    public boolean itFired() {
        return this.getEntityData().get(IT_FIRED);
    }

    /**
     * 创建实体实例。
     *
     * @param packet  生成数据包
     * @param worldIn 所在世界
     * @return 剑雨实体实例
     */
    public static BaseSwordRainEntity createInstance(PlayMessages.SpawnEntity packet, Level worldIn) {
        return new BaseSwordRainEntity(SlashBladeCompatEntities.BASE_SWORD_RAIN.get(), worldIn);
    }

    /**
     * 每帧更新实体状态。
     */
    @Override
    public void tick() {
        if (!this.itFired()

                && this.getVehicle() == null) {
            this.startRiding(this.getOwner(), true);
        }

        // 在发射前保持与玩家相同的朝向
        if (!this.itFired() && this.getOwner() != null) {
            this.setYRot(-this.getOwner().getYRot());
            this.setXRot(-this.getOwner().getXRot());
        }

        super.tick();
    }

    /**
     * 处理骑乘状态下的逻辑。
     */
    @Override
    public void rideTick() {
        doRide();

    }

    /**
     * 执行骑乘逻辑，包括发射和移动。
     */
    private void doRide() {
        if (this.itFired() && this.fireTime <= this.tickCount) {
            this.faceEntityStandby();
            this.stopRiding();
            this.tickCount = 0;

            if (this.entityData.get(FORWARD)) {
                handleForwardShot();
            } else {
                handleDownwardShot();
            }
        } else {
            handleStandbyState();
        }
    }

    /**
     * 处理向前射击逻辑。
     */
    public void handleForwardShot() {
        Entity sender = getOwner();
        if (sender != null) {
            this.entityData.set(VISIBLE, true);
            Level worldIn = sender.level();

            // 寻找最近的目标实体
            Vec3 center = new Vec3(this.getX(), this.getY(), this.getZ());
            List<Entity> entities = this.level().getEntitiesOfClass(Entity.class,
                            new AABB(center, center).inflate(100.0), e -> true)
                    .stream()
                    .sorted(Comparator.comparingDouble(e -> e.distanceToSqr(center)))
                    .toList();

            Optional<Entity> target = entities.stream()
                    .filter(e -> e instanceof LivingEntity &&
                            ((LivingEntity) e).getHealth() > 0 &&
                            e != getOwner() &&
                            e != this)
                    .findFirst();

            // 计算目标位置或使用视线方向
            Vec3 targetPos = target.map(e -> new Vec3(e.getX(), e.getY() + e.getEyeHeight() * 0.5, e.getZ()))
                    .orElseGet(() -> {
                        Vec3 start = sender.getEyePosition(1.0f);
                        Vec3 end = start.add(sender.getLookAngle().scale(40));
                        HitResult result = worldIn.clip(new ClipContext(start, end,
                                ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, sender));
                        return result.getLocation();
                    });

            // 计算方向并发射
            Vec3 pos = this.getPosition(0.0f);
            Vec3 dir = targetPos.subtract(pos).normalize();

            // 设置实体朝向目标方向
            float yaw = (float) Math.toDegrees(Math.atan2(dir.x, dir.z));
            float pitch = (float) Math.toDegrees(Math.asin(dir.y));
            this.setYRot(yaw);
            this.setXRot(pitch);

            this.shoot(dir.x, dir.y, dir.z, 2.0f, 1.0f);
        }
    }

    /**
     * 处理向下射击逻辑。
     */
    private void handleDownwardShot() {
        Vec3 dir = new Vec3(0.0, -1.0, 0.0);
        this.shoot(dir.x, dir.y, dir.z, 4.0F, 2.0F);
    }

    /**
     * 处理待机状态逻辑。
     */
    private void handleStandbyState() {
        this.setDeltaMovement(Vec3.ZERO);
        if (this.canUpdate()) {
            this.baseTick();
        }

        if (!this.itFired()) {
            this.fireTime = this.tickCount + BASE_DELAY + this.getDelay();
            this.doFire();
        }
    }

    /**
     * 设置实体朝向为待机状态。
     */
    void faceEntityStandby() {
        this.setPos(this.position());
        this.setRot(this.getYRot(), getRoll());
    }

    /**
     * 设置实体散布位置。
     *
     * @param basePos 基础位置
     */
    public void setSpread(Vec3 basePos) {
        double areaSize = 2.5;
        double offsetX = (this.random.nextDouble() * 2.0 - 1.0) * areaSize;
        double offsetZ = (this.random.nextDouble() * 2.0 - 1.0) * areaSize;
        this.setPos(basePos.x + offsetX, basePos.y, basePos.z + offsetZ);
    }

    /**
     * 处理命中实体事件。
     *
     * @param hitResult 命中结果
     */
    @Override
    protected void onHitEntity(EntityHitResult hitResult) {

        Entity targetEntity = hitResult.getEntity();
        if (targetEntity instanceof LivingEntity) {
            LivingEntity livingTarget = (LivingEntity) targetEntity;
            KnockBacks.cancel.action.accept(livingTarget);
            StunManager.setStun(livingTarget);
            livingTarget.invulnerableTime = 0;

//            // 造成伤害
//            if (!this.level().isClientSide&&this.getOwner() instanceof LivingEntity) {
//                livingTarget.hurt(this.damageSources().indirectMagic(this, (LivingEntity) this.getOwner()), 5.0F);
//            } else {
//                livingTarget.hurt(this.damageSources().magic(), 5.0F);
//            }
        }
        super.onHitEntity(hitResult);
    }

    /**
     * 尝试销毁实体。
     */
    @Override
    protected void tryDespawn() {
        ++this.ticksInGround;
        if (this.ticksInGround >= ON_GROUND_LIFE_TIME) {
            this.burst();
        }
    }
}